#include "graph.h"

bool visit(vexNode & vex){
    std::cout << "node value :" <<  vex.vex_value << "\t weights : ";
    for(arcNode * p = vex.first_arc; p != NULL; p = p->next_arc){
        std ::cout << "  " << p->weight;
    }
    std::cout << std::endl;

    return true;
}

int startMenu(){
    std::cout << "========================================================================" << std::endl;
    std::cout << "==========================图论模型的系统联调与测试=======================" << std::endl;
    std::cout << "========================================================================" << std::endl;
    std::cout << "～图的创建：      1、无向图（类型2）   2、无向网（类型3）"<< std::endl;
    // std::cout << "～图的存储结构：   1、临接矩阵         2、 临接表" << std::endl;
    std::cout << "~请选择要进行的测试内容：" << std::endl;
    std::cout << "～1、图的输入与输出" << std::endl
              << "～2、图的最小生成树的求解" << std::endl
              << "～3、图的最短路径问题求解" << std::endl;
    std::cout << "请输入要进行的测试：" << std::endl;
    int ret = 100;
    std::cin >> ret;
    int cout = 0;
    while(ret <= 0 || ret > 3){
        if(cout++ > 3)exit(1);
        std::cout << "输入错误，请重新输入：";
        std::cin >> ret;
    }
    return ret-1;
}

bool io_test(){
    std::cout << "临接表结构图的输入：" << std::endl;
    alGraph al_graph;
    createALGraph(al_graph);
    std:: cout << "请问是否将图输出？(0表示不输出，1表示深度搜索输出，2表示广度优先搜索输出)" << std::endl;
    int options = 0;
    std::cin >> options;
    if(1 == options){
        dfsTraverse(al_graph, visit);
    }
    else if(2 == options){
        bfsTraverse(al_graph, visit);
    }

    std::cout << "临接矩阵结构输入：" << std::endl;
    matGraph mat_graph;
    createMGraph(mat_graph);
    std::cout << "临接矩阵就不输出了" << std::endl;
    return true;
}

bool min_tree_test(){
    std::cout << "临接矩阵结构图的输入：" << std::endl;
    matGraph mat_graph;
    createMGraph(mat_graph);
    while(!isConnected(mat_graph)){
        std::cout << "此图非连通图，请重新输入：" << std::endl;
        createMGraph(mat_graph);
    }
    std:: cout << "请输入求解方案（1-Primer， 2-Kruskal）：" << std::endl;
    int options;
    std::cin >> options;
    int cout = 0;
    while(2!=options && 1!=options){
        if(cout++ > 3)exit(1);
        std::cout << "请重新输入: " << std::endl;
        std::cin >> options;
    }
    if(1==options){
        std::cout << "请输入最小生成树的根节点（0-" << mat_graph.vex_num-1 << "）："<< std::endl;
        int start = -1;
        int cout = 0;
        std::cin >> start;
        while(start < 0 || start >= mat_graph.vex_num){
            if(cout++ > 3)exit(1);
            std::cout << "输入错误，请重新输入：";
            std::cin >> start;
        }
        miniSpanTreePrime(mat_graph, start);
    }
    if(2==options){
        miniSpanTreeKruskal(mat_graph);
    }

    return true;
}

bool shortest_path(){
    std::cout << "临接矩阵结构图的输入：" << std::endl;
    matGraph mat_graph;
    createMGraph(mat_graph);
    while(!isConnected(mat_graph)){
        std::cout << "此图非连通图，请重新输入：" << std::endl;
        createMGraph(mat_graph);
    }
    std::cout << "请输入求解方案（1-单源最短路径求解， 2-任意两点之间最短路径求解）" << std::endl;
    int options = 0;
    std::cin >> options;
    while(2!=options && 1!=options){
        std::cout << "请重新输入: " << std::endl;
        std::cin >> options;
    }
    if(2 == options){
        fPath path;
        dMatrix dist;
        shortPathFloyd(mat_graph, path, dist);
        std::cout << "请输入起点：" << std::endl;
        int start = -1;
        int end = -1;
        std::cin >> start;
        while(start < 0 || start >=mat_graph.vex_num){
            std::cout << "输入有误，请重新输入：";
            std::cin >> start;
        }
        std::cout << "请输入终点：" << std::endl;
        std::cin >> end;
        while(end < 0 || end >=mat_graph.vex_num){
            std::cout << "输入有误，请重新输入：";
            std::cin >> end;
        }
        putPathFloyd(mat_graph, path, start, end);
    }else if(1 == options){
        sPathTable t;
        pathMatrix pm;
        int origin = -1;
        std::cout << "请输入源点位置：" << std::endl;
        std::cin >> origin;
        while(origin < 0 || origin >=mat_graph.vex_num){
            std::cout << "输入有误，请重新输入：";
            std::cin >> origin;
        }
        shortPathDijkstra(mat_graph, pm, t, origin);
        putPathDijkstra(mat_graph, pm);
    }

    return true;
}

int main(){
    bool (*test_func[3])() = {io_test, min_tree_test, shortest_path};
    char e = '0';
    while(e == '0'){
        int t = startMenu();
        test_func[t]();
        std::cout << "是否退出？(0表示继续)";
        std::cin >> e;
    }
    return 0;
}